/*
 * @Description:
 * @Version: 3.0
 * @Autor: biao.hu
 * @Date: 2021-10-18 20:29:13
 * @LastEditors: biao.hu
 * @LastEditTime: 2021-10-19 09:33:55
 */
package channel

import (
	"errors"
	"fmt"
	"os"
	"time"
)

func Ch() {
	var ch = make(chan int)

	defer close(ch)
	go func(ch chan int) {
		ch <- 1
		ch <- 2
		ch <- 3
		fmt.Println("send finished")
	}(ch)

	for {
		select {
		case i := <-ch:
			fmt.Println("receive", i)
		case <-time.After(time.Second):
			fmt.Println("time out")
			os.Exit(1)
		}

	}
}

func ChLimit() {
	var ch = make(chan int)
	defer close(ch)
	// 防止误发送(chan<-)和接收(<-chan)，这里设置为只能发送模式chan<-
	go func(ch chan<- int) {
		ch <- 1
		ch <- 2
		ch <- 3
		fmt.Println("send finished")
	}(ch)

	for {
		select {
		case i := <-ch:
			fmt.Println("receive", i)
		case <-time.After(time.Second):
			fmt.Println("time out")
			os.Exit(1)
		}

	}
}

func ChClose() {
	var ch = make(chan int)
	defer close(ch)
	// 防止误发送(chan<-)和接收(<-chan)，这里设置为只能发送模式chan<-
	go func(ch chan<- int) {
		ch <- 1
		ch <- 2
		ch <- 3
		close(ch) // 手动关闭
		fmt.Println("send finished")
	}(ch)

	for {
		select {
		case i, ok := <-ch:
			if ok {
				fmt.Println("receive", i)
			} else {
				fmt.Println("channel close")
				os.Exit(1)
			}

		case <-time.After(time.Second):
			fmt.Println("time out")
			os.Exit(1)
		}

	}
}

func ChTash() {
	var doneCh = make(chan struct{})
	var errCh = make(chan error)
	go func(doChan chan<- struct{}, errCh chan<- error) {
		if time.Now().Unix()%2 == 0 {
			doChan <- struct{}{}
		} else {
			errCh <- errors.New("unix time is an odd")
		}
	}(doneCh, errCh)

	select {
	case <-doneCh:
		fmt.Println("done")
	case err := <-errCh:
		fmt.Println("get an error", err)
	case <-time.After(time.Second):
		fmt.Println("time out")
	}
}

func ChBuffer() {
	var ch = make(chan int, 3)
	go func(ch chan int) {
		ch <- 1
		ch <- 2
		ch <- 3
		fmt.Println("send finished")
	}(ch)

	for {
		select {
		case i := <-ch:
			fmt.Println("receive", i)
		case <-time.After(time.Second):
			fmt.Println("time out")
			os.Exit(1)
		}
	}
}

func ChBufferRange() {
	var ch = make(chan int, 3)
	go func(ch chan int) {
		ch <- 1
		ch <- 2
		ch <- 3
		close(ch)
		fmt.Println("send finished")
	}(ch)

	for i := range ch {
		fmt.Println("receive", i)
	}
}
